package com.zenithmind.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import com.zenithmind.task.mapper.TaskCategoryMapper;
import com.zenithmind.task.pojo.entity.TaskCategory;
import com.zenithmind.task.pojo.query.TaskCategoryQuery;
import com.zenithmind.task.pojo.vo.TaskCategoryVO;
import com.zenithmind.task.service.TaskCategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 任务分类服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TaskCategoryServiceImpl extends ServiceImpl<TaskCategoryMapper, TaskCategory> implements TaskCategoryService {

    @Override
    public PageResult<TaskCategoryVO> getCategoryPage(TaskCategoryQuery query) {
        Page<TaskCategory> page = query.toPage();
        
        LambdaQueryWrapper<TaskCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getName()), TaskCategory::getName, query.getName())
               .eq(StringUtils.hasText(query.getParentId()), TaskCategory::getParentId, query.getParentId())
               .eq(query.getStatus() != null, TaskCategory::getStatus, query.getStatus())
               .eq(query.getCategoryType() != null, TaskCategory::getIsSystem, query.getCategoryType());
        
        if (!StringUtils.hasText(query.getCreatorId())) {
            wrapper.and(w -> w.eq(TaskCategory::getCreatorId, UserContext.getUserId())
                              .or()
                              .eq(TaskCategory::getIsSystem, 1));
        } else {
             wrapper.eq(TaskCategory::getCreatorId, query.getCreatorId());
        }
               
        wrapper.orderByAsc(TaskCategory::getSortOrder)
               .orderByDesc(TaskCategory::getCreateTime);
        
        IPage<TaskCategory> result = page(page, wrapper);
        
        List<TaskCategoryVO> voList = result.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
        
        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public List<TaskCategoryVO> getCategoryTree(String userId) {
        LambdaQueryWrapper<TaskCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskCategory::getStatus, 1)
               .and(w -> w.eq(TaskCategory::getCreatorId, userId)
                         .or()
                         .eq(TaskCategory::getIsSystem, 1)) // 系统分类或用户创建的分类
               .orderByAsc(TaskCategory::getSortOrder);
        
        List<TaskCategory> allCategories = list(wrapper);
        List<TaskCategoryVO> voList = allCategories.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
        
        return buildCategoryTree(voList);
    }

    @Override
    public TaskCategoryVO getCategoryById(String id, String userId) {
        TaskCategory category = getById(id);
        if (category == null) {
            throw new BusinessException("分类不存在");
        }
        
        // 权限检查
        if (!checkCategoryPermission(category, userId)) {
            throw new BusinessException("无权限访问该分类");
        }
        
        return convertToVO(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createCategory(TaskCategory category, String userId) {
        // 设置创建者信息
        category.setCreatorId(userId);
        category.setCreatorName(UserContext.getUsername());
        
        // 设置默认值
        if (category.getStatus() == null) {
            category.setStatus(1); // 启用
        }
        if (category.getIsSystem() == null) {
            category.setIsSystem(0); // 用户分类, 1:系统, 0:用户
        }
        if (category.getSortOrder() == null) {
            category.setSortOrder(0);
        }
        
        // 设置分类路径
        if (StringUtils.hasText(category.getParentId())) {
            TaskCategory parentCategory = getById(category.getParentId());
            if (parentCategory != null) {
                category.setLevel(parentCategory.getLevel() + 1);
                category.setPath(parentCategory.getPath() + "/" + category.getName());
            }
        } else {
            category.setLevel(1);
            category.setPath("/" + category.getName());
        }
        
        boolean result = save(category);
        
        if (result) {
            log.info("用户 {} 创建分类: {}", userId, category.getName());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCategory(TaskCategory category, String userId) {
        TaskCategory existingCategory = getById(category.getId());
        if (existingCategory == null) {
            throw new BusinessException("分类不存在");
        }
        
        // 权限检查
        if (!checkCategoryPermission(existingCategory, userId)) {
            throw new BusinessException("无权限编辑该分类");
        }
        
        boolean result = updateById(category);
        
        if (result) {
            log.info("用户 {} 更新分类: {}", userId, category.getName());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCategory(String id, String userId) {
        TaskCategory category = getById(id);
        if (category == null) {
            throw new BusinessException("分类不存在");
        }
        
        // 权限检查
        if (!checkCategoryPermission(category, userId)) {
            throw new BusinessException("无权限删除该分类");
        }
        
        // 检查是否有子分类
        LambdaQueryWrapper<TaskCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskCategory::getParentId, id);
        long childCount = count(wrapper);
        
        if (childCount > 0) {
            throw new BusinessException("存在子分类，无法删除");
        }
        
        // TODO: 检查是否有关联的任务
        
        boolean result = removeById(id);
        
        if (result) {
            log.info("用户 {} 删除分类: {}", userId, category.getName());
        }
        
        return result;
    }

    @Override
    public Boolean moveCategory(String id, String newParentId, String userId) {
        // TODO: 实现分类移动
        return false;
    }

    @Override
    public List<TaskCategoryVO> getUserCategories(String userId) {
        LambdaQueryWrapper<TaskCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskCategory::getStatus, 1)
               .eq(TaskCategory::getCreatorId, userId)
               .orderByAsc(TaskCategory::getSortOrder);
        
        List<TaskCategory> categories = list(wrapper);
        
        return categories.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    public List<TaskCategoryVO> getSystemCategories() {
        LambdaQueryWrapper<TaskCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskCategory::getStatus, 1)
               .eq(TaskCategory::getIsSystem, 1) // 系统分类
               .orderByAsc(TaskCategory::getSortOrder);
        
        List<TaskCategory> categories = list(wrapper);
        
        return categories.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    public Boolean updateCategoryTaskCount(String categoryId) {
        // TODO: 实现任务数量更新
        return false;
    }

    // ==================== 辅助方法 ====================

    /**
     * 转换为VO对象
     */
    private TaskCategoryVO convertToVO(TaskCategory category) {
        TaskCategoryVO vo = BeanCopyUtils.copyBean(category, TaskCategoryVO.class);
        
        // 设置分类类型文本
        vo.setCategoryTypeText(category.getIsSystem() == 1 ? "系统分类" : "用户分类");
        
        // 设置状态文本
        vo.setStatusText(category.getStatus() == 1 ? "启用" : "禁用");
        
        return vo;
    }

    /**
     * 构建分类树
     */
    private List<TaskCategoryVO> buildCategoryTree(List<TaskCategoryVO> categories) {
        Map<String, List<TaskCategoryVO>> parentMap = categories.stream()
            .filter(category -> StringUtils.hasText(category.getParentId()))
            .collect(Collectors.groupingBy(TaskCategoryVO::getParentId));
        
        List<TaskCategoryVO> rootCategories = categories.stream()
            .filter(category -> !StringUtils.hasText(category.getParentId()))
            .collect(Collectors.toList());
        
        for (TaskCategoryVO category : rootCategories) {
            setChildren(category, parentMap);
        }
        
        return rootCategories;
    }

    /**
     * 设置子分类
     */
    private void setChildren(TaskCategoryVO category, Map<String, List<TaskCategoryVO>> parentMap) {
        List<TaskCategoryVO> children = parentMap.get(category.getId());
        if (children != null && !children.isEmpty()) {
            category.setChildren(children);
            for (TaskCategoryVO child : children) {
                setChildren(child, parentMap);
            }
        } else {
            category.setChildren(new ArrayList<>());
        }
    }

    /**
     * 检查分类权限
     */
    private Boolean checkCategoryPermission(TaskCategory category, String userId) {
        // 系统分类所有人可见
        if (category.getIsSystem() == 1) {
            return true;
        }
        
        // 用户分类只有创建者可编辑
        return category.getCreatorId().equals(userId);
    }
}
